package net.chathu.airgw.crypto 
{
	/**
	 * ...
	 * @author ze
	 */
	public class RC4 extends Cipher
	{
		protected var i_:int;
		protected var j_:int;
		
		public function RC4()
		{
			super(256, 1, 64);
		}

   
		override public function copy():Cipher
		{
			return new RC4();
		}

		override public function setKey(abyte0:Array):void
		{
			//byte abyte1[] = new byte[256];
			var abyte1:Array = new Array();
			for (var c:int = 0; c < 256; c++)
			{
				abyte1[c] = 0;
			}
			var i:int = abyte0.length;
			for(var j:int = 0; j < 256; j++)
			{
				key[j] = j & 0xff;
				abyte1[j] = abyte0[j % i];
			}

			var l:int;
			for(var k:int = l = 0; k < 256; k++)
			{
				l = l + key[k] + abyte1[k] & 0xff;
				//byte byte0 = key[k];
				var byte0:int = key[k] & 0xff;
				key[k] = key[l];
				key[l] = byte0;
			}

			i_ = j_ = 0;
		}

		private final function next():int
		{
			i_ = i_ + 1 & 0xff;
			j_ = j_ + key[i_] & 0xff;
			//byte byte0 = key[i_];
			var byte0:int = key[i_] & 0xff;
			key[i_] = key[j_];
			key[j_] = byte0;
			return (key[key[i_] + key[j_] & 0xff]) & 0xff;
		}

		override public function encrypt(abyte0:Array, i:int, abyte1:Array, j:int, k:int):void
		{
			for (; k > 0; k--)
			{
				//abyte1[j++] = (byte)(abyte0[i++] ^ next());
				abyte1[j++] = (abyte0[i++] ^ next()) & 0xff;
			}

		}

		override public function encryptArray(abyte0:Array):void
		{
			var i:int = abyte0.length;
			var j:int = 0;
			for(; i > 0; i--)
			{
				//abyte0[j] = (byte)(abyte0[j] ^ next());
				abyte0[j] = (abyte0[j] ^ next()) & 0xff;
				j++;
			}

		}

		override public function decrypt(abyte0:Array, i:int, abyte1:Array, j:int, k:int):void
		{
			encrypt(abyte0, i, abyte1, j, k);
		}

		override public function decryptArray(abyte0:Array):void
		{
			encryptArray(abyte0);
		}
		
	}

}